/*
 * @Author: silence
 * @Date: 2022-02-07 16:36:06
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2022-08-02 11:52:35
 * @Description: 文件头部注释
 * @FilePath: /lib/utils/api/ApiUtils.dart
 */

import 'dart:convert';
import 'dart:typed_data';

import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';

import '../config/AppInfo.dart';
import '../utils/Tool/MyLog.dart';
import '../utils/Tool/MyTools.dart';
import '../utils/userbloc/user_bloc.dart';
import 'NetApiInterceptor.dart';

// import 'package:dio_http_cache/dio_http_cache.dart';
import 'NetParamInterceptor.dart';
import 'R.dart';

class ApiUtils {
  static String getMethod = 'get';
  static String postMethod = 'post';
  static String putMethod = 'PUT';

  /// @description: 初始化dio
  /// @param {*}
  /// @return {*}
  static Dio initDio(
      {Map<String, dynamic>? headers,
      Map<String, dynamic>? extra,
      bool isUseBaseUrl = true,
      bool isFormData = false}) {
    BaseOptions baseOptions = MyTools.mapIsEmpty(headers)
        ? BaseOptions(
            connectTimeout: RequestTimeout,
            receiveTimeout: RequestTimeout,
            extra: extra)
        : BaseOptions(
            headers: headers,
            connectTimeout: RequestTimeout,
            receiveTimeout: RequestTimeout,
            extra: extra);

    // 是否使用host
    if (isUseBaseUrl) {
      baseOptions.baseUrl = BaseUrl;
    } else {
      baseOptions.baseUrl = convertUrl;
    }
    Dio dio = Dio(baseOptions);
    // 添加缓存拦截器
    // dio.interceptors.add(NetCacheInterceptor());
    // 添加公共参数处理拦截器
    dio.interceptors.add(NetParamInterceptor(
        isNeedHandler: isUseBaseUrl, isFormData: isFormData));
    // 添加接口处理拦截器
    dio.interceptors.add(NetApiInterceptor(isNeedHandler: isUseBaseUrl));
    // 缓存
    // dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: BaseUrl)).interceptor);
    // 解决证书验证问题，验证强制返回true：
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
        (client) {
      client.badCertificateCallback = (cert, host, port) {
        return true;
      };
      // 设置代理
      // if (Constant.PROXY_PATH.isNotEmpty) {
      //   client.findProxy = (url) => "PROXY ${Constant.PROXY_PATH}";
      // }
    };
    return dio;
  }

  // static Dio initDownImgDio() {
  //   BaseOptions baseOptions = BaseOptions(
  //       connectTimeout: 10000,
  //       receiveTimeout: 10000,
  //       responseType: ResponseType.bytes);
  //
  //   Dio dio = Dio(baseOptions);
  //   // 解决证书验证问题，验证强制返回true：
  //   (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
  //       (client) {
  //     client.badCertificateCallback = (cert, host, port) {
  //       return true;
  //     };
  //   };
  //   return dio;
  // }

  /// @description: 发送网络请求
  /// @param method 请求方式; path 请求的地址; param 请求参数; isFormData 是否表单数据; headers 请求头; isUseBaseUrl 是否使用host;showErrorToast 是否显示网络错误提示
  /// @return {*}
  static Future<Map<String, dynamic>?> methodAwait(String method, String url,
      {dynamic? param,
      Map<String, dynamic>? extra,
      bool isFormData = false,
      Map<String, dynamic>? headers,
      bool isUseBaseUrl = true,
      bool isShowLog = false,
      bool showErrorToast = true,
      Options? options,
      CancelToken? cancelToken}) async {
    late Dio dio;
    late Map<String, dynamic> result;

    if (param == null) param = Map(); // 处理参数为空的情况

    String? auth = await UserBlocTool.getUserAuth();
    if (MyTools.stringIsEmpty(auth)) {
      return null;
    }

    try {
      var response = null;
      dio = initDio(
          headers: headers,
          isUseBaseUrl: isUseBaseUrl,
          extra: extra,
          isFormData: isFormData);
      if (method == getMethod) {
        dynamic tempParam = param;
        response = await dio.get(
          url,
          // queryParameters: tempParam,
          cancelToken: cancelToken,
          options: options,
        );
        //print("3333333333");
      } else if (method == postMethod) {
        dynamic tempParam = param;
        response = await dio.post(
          url,
          data: tempParam,
          cancelToken: cancelToken,
          // options: buildCacheOptions(Duration(days: 7)),
        );
      } else if (method == putMethod) {
        dynamic tempParam = param;
        dio.options.headers['Content-Type'] = 'multipart/form-data';
        response = await dio.put(
          url,
          data: tempParam,
          // options: Options(responseType: ResponseType.bytes),
          options: options,
          cancelToken: cancelToken,
        );
      }
      var data = response.data;
      if (method == putMethod) {
        if (data is Map) {
          result = data as Map<String, dynamic>;
          result["code"] = 0;
          if (result["SplitResult"] != null) {
            if (result["SplitResult"]["ZippedPages"] != null) {
              result["data"] = result["SplitResult"]["ZippedPages"]["Href"];
            }
          }
        } else {
          Uint8List uint8list = data;
          result = {"code": 0, "data": uint8list};
        }
      } else {
        if (data is String) {
          result = json.decode(data);
        } else if (data is Map) {
          result = data as Map<String, dynamic>;
        } else {
          Uint8List uint8list = data;
          result = {"code": 0, "data": uint8list};
        }
        print("data$data");
      }
    } catch (e) {
      result = {'error': e};
      if (showErrorToast) {
        // MyToast.show('网络不给力，请稍后重试');
        print(result);
      }
    } finally {
      // 打印请求的信息
      if (isShowLog) {
        Mylog.p(
            url: (dio.options.baseUrl + url),
            param: {'headers': dio.options.headers, 'body': param},
            result: result);
      }

      return result;
    }
  }
}

/// @description: 接口处理：非列表接口使用
/// @param {
///  api：接口处理函数
///  success：成功回调函数
///  failure：失败回调函数
///  promptText：自定义loading提示
///  showLoading: 是否loading
///  showErrorToast：是否显示错误提示
/// }
/// @return {*}
Future apiShow({
  required Future api,
  required Function(dynamic) success,
  Function(dynamic)? failure,
  String? promptText = "加载中...",
  bool showLoading = false,
  bool showErrorToast = true,
  Function()? onDismiss,
}) async {
  R result = R();

  try {
    result = await api;
  } catch (e) {
    result.error = Future.error(e);
    // if (e is MyFutureBuilderException) {
    //   MyFutureBuilderException myFutureBuilderException =
    //       e as MyFutureBuilderException;
    //   result.message = myFutureBuilderException.message;
    // }
  } finally {
    //将loading弹窗消失掉
    // if (showLoading) ARoute.finish(context);

    // 网络异常
    if (result.error != null) {
      if (failure != null) {
        result.code = 404;
        failure(result);
      }
    } else {
      // 接口正常返回
      if (result.code != null && result.code == 0) {
        // 数据获取成功
        success(result);
      } else {
        // 数据获取失败
        if (failure != null) {
          failure(result);
        }
      }
    }
  }
}
